package android_design_mode.chapter002_singleton;

import headfirst.singleton.subclass.Singleton;

public class Test {

    public static void main(String[] args) {

        CEO c1 = CEO.getCeo();
//        CEO c2 = new CE0();
        CEO c3 = CEO.getCeo();

        System.out.println(c1.toString());
        System.out.println(c3);

        SingletonLanHan singletonLanHan001 = SingletonLanHan.getInstance();
        SingletonLanHan singletonLanHan002 = SingletonLanHan.getInstance();
        System.out.println("懒汉式/不推荐");
        System.out.println(singletonLanHan001);
        System.out.println(singletonLanHan002);


        System.out.println("enum/推荐");
        SingleTonEnum singleTonEnum01 = SingleTonEnum.INSTANCE;
        SingleTonEnum singleTonEnum02 = SingleTonEnum.INSTANCE;
        System.out.println(singleTonEnum01.toString());
        System.out.println(singleTonEnum02);
        singleTonEnum01.doXXX();

        SingletonStaticInnerClass.getInstance();

    }
}

/**
 * 懒汉式
 */
class SingletonLanHan {

    private static SingletonLanHan instance;

    private SingletonLanHan() {
    }

    public static synchronized SingletonLanHan getInstance() {
        if (instance == null) {
            instance = new SingletonLanHan();
        }
        return instance;
    }

}

/**
 * DCL - double check lock
 */
class SingletonDCL {
    private static SingletonDCL instance = null;

    private SingletonDCL() {
    }

    public static SingletonDCL getInstance() {
        if (instance == null) {
            // 只进入一次
            synchronized (SingletonDCL.class) {
                instance = new SingletonDCL();
            }
        }
        return instance;
    }
}

/**
 * 推荐
 */
class SingletonStaticInnerClass {
    private SingletonStaticInnerClass() {
    }

    public static SingletonStaticInnerClass getInstance() {
        return SingletonHolder.instance;
    }

    private static class SingletonHolder {
        private static final SingletonStaticInnerClass instance = new SingletonStaticInnerClass();
    }
}


/**
 *
 */
enum SingleTonEnum {
    INSTANCE;

    public void doXXX() {
        System.out.println("SingleTonEnum");
    }


}

